/*
 * @brief 存在多种隐患的 observer
 */
#include <iostream>
#include <vector>


// ------ Observable ------
class Observer;
class Observable {
public:
    void register_(Observer* x);
    void unregister(Observer* x);
    void notifyAll();
private:
    std::vector<Observer*> _observers;
};

// ------ Observer ------
class Observer {
public:
    Observer(Observable* s) {
        // 危险，没有构造完成就被使用
        s->register_(this);
        _subject = s;
    }
    virtual ~Observer() {
        _subject->unregister(this);
    }
    virtual void update() = 0;
private:
    Observable* _subject;
};

void Observable::register_(Observer* x) {
    _observers.push_back(x);
}

void Observable::unregister(Observer* x) {
    std::vector<Observer*>::iterator it = _observers.begin();
    for (; it != _observers.end(); ++it) {
        if (*it == x) {
            _observers.erase(it);
            break;
        }
    }
}

void Observable::notifyAll() {
    for (Observer* x : _observers) {
        // 危险，x 真的还在吗？
        x->update();
    }
}

// ------ Foo ------
class Foo: public Observer {
public:
    Foo(const char* name, Observable* s): _name(name), Observer(s) {
    }
    ~Foo() {};
    void update() {
        std::cout << _name << " is notified" << std::endl;
    }
private:
    std::string _name;
};

// ------ main ------
int main() {
    Observable observable;
    Foo *f1 = new Foo("allen", &observable);
    Foo *f2 = new Foo("luffy", &observable);
    Foo *f3 = new Foo("zoro", &observable);
    Foo *f4 = new Foo("sanji", &observable);

    delete f1;

    // segment fault
    observable.notifyAll();
}
